# @Time : 2021/8/3 14:59
# @Author : Li Kunlun
# @Description : 自动求梯度
from mxnet import autograd, nd

"""
1、对 y=2*x^T*X 求关于列向量x的梯度
"""
x = nd.arange(4).reshape((4, 1))
# 1、先调用attach_grad函数来申请存储梯度所需要的内存
x.attach_grad()

# 2、调用record函数来要求MXNet记录与求梯度有关的计算
with autograd.record():
    y = 2 * nd.dot(x.T, x)

# 3、通过调用backward函数自动求梯度
y.backward()

# 4、验证计算梯度是否正确
"""
可以理解assert断言语句为raise-if-not，用来测试表示式，其返回值为假，就会触发异常。
"""
assert (x.grad - 4 * x).norm().asscalar() == 0
# [[  0.]
#  [  4.]
#  [  8.]
#  [ 12.]]
# <NDArray 4x1 @cpu(0)>
print(x.grad)

print("-----------------------训练模式和预测模式------------------------")
"""
1、输出
    False
    True
2、在调用record函数后，MXNet会记录并计算梯度。此外，
默认情况下autograd还会将运行模式从预测模式转为训练模式
"""
print(autograd.is_training())
with autograd.record():
    print(autograd.is_training())
